package com.cqemme.activitiservice.service.node;

import com.alibaba.fastjson.JSONObject;
import com.cqemme.activitiservice.feign.WebsocketService;
import com.cqemme.activitiservice.po.AlarmMessageInfo;
import com.cqemme.activitiservice.service.ActivitiUtilService;
import com.cqemme.activitiservice.service.CommonService;
import com.cqemme.activitiservice.utils.EmptyChecker;
import com.cqemme.activitiservice.utils.JedisUtil;
import com.cqemme.comm.po.CurrentLoginUser;
import com.cqemme.comm.po.Result;
import com.cqemme.comm.utils.ResultCodeMsg;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.*;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class SosService {

    @Value("${node.api.savaProcessAtReach}")
    private String savaProcessAtReachUrl;

    @Value("${node.api.savaProcessAtOver}")
    private String savaProcessAtOverUrl;

    @Value("${node.api.saveInsOfGearTask}")
    private String saveInsOfGearTaskUrl;

    @Value("${gpsToAddressUrl}")
    private String gpsToAddressUrl;

    @Value("${process.type.sosAvaUrl}")
    private String sosAvaUrl;

    @Value("${process.type.fireAvaUrl}")
    private String fireAvaUrl;

    @Value("${process.type.pillarAvaUrl}")
    private String pillarAvaUrl;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private HistoryService historyService;

    @Resource
    private ManagementService managementService;

    @Resource
    private TaskService taskService;


    @Resource
    private RepositoryService repositoryService;

    @Resource
    private CommonService commonService;

    @Autowired
    private ActivitiUtilService activitiUtilService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private JedisUtil jedisUtil;

    @Resource
    private WebsocketService websocketService;


    /**
     * 学生校徽报警处理 - 启动校徽报警流程
     * 1：根据学校id、"sos-security"、"sos-security-room" 查出数据
     * 2：查出一条数据说明此学校只有一种sos报警流程图，就直接启动
     * 3：查出两条数据说明此学校有保安前往和保安队长分配任务报警流程图
     * 先对比所有保安和学生位置，如都过远，就启动保安队长分配任务报警流程图
     * 如较学生较近，直接启动此保安直接前往流程图
     *
     * @param data
     */
    public Result handleSoSAlarm(String data) {
        Result result = new Result();
        Map<String, Object> studentMap = JSONObject.parseObject(data, Map.class);
        String schoolId = studentMap.get("schoolId").toString();
        String schoolName = ((Map) studentMap.get("Student")).get("studentName") + "";
        //查学校sos报警流程图启动key
        String orgProcessInstanceById = commonService.getOrgProcessDefinitionId(Integer.parseInt(schoolId), "sos-security");

        //判断有无Gps地址化
        Map<String, Object> gps = (Map<String, Object>) (((List) studentMap.get("Gps")).get(0));
        if (EmptyChecker.isEmpty(gps.get("Address"))) {
            String gpsUrl = gpsToAddressUrl + "&extensions_poi=0&location=" + gps.get("Latitude") + "," + gps.get("Longitude");
            try {
                String addressStr = restTemplate.getForObject(gpsUrl, String.class);
                Map<String, Object> addressMap = JSONObject.parseObject(addressStr, Map.class);
                gps.put("Address", (((Map) (addressMap.get("result"))).get("formatted_address")).toString().split(";")[0]);
            } catch (RestClientException e) {
                gps.put("Address", "");
            }
        }

        //启动学生校徽报警流程
        Map<String, Object> var = new HashMap<>();
        var.put("student", JSONObject.toJSONString(studentMap));
        var.put("schoolId", schoolId);
        var.put("chartType", "sos-security");
        var.put("begin_start_description", "【" + schoolName + "】触发sos报警");
        runtimeService.startProcessInstanceById(orgProcessInstanceById,var);
        result.setStatusCode(ResultCodeMsg.CODE_200);
        return result;
    }

    /**
     * 报警柱/火灾触发报警
     *
     * @param data
     */
    public Result pillarAlarm(String data) {
        Result result = new Result();
        Map<String, Object> reqMap = JSONObject.parseObject(data, Map.class);
        String schoolId = reqMap.get("orgCode").toString();
        //查学校报警柱流程图启动key
        String orgProcessInstanceById = commonService.getOrgProcessDefinitionId(Integer.parseInt(schoolId), "pillar-alarm");

        if(null != orgProcessInstanceById){
            //启动报警柱报警流程
            Map<String, Object> var = new HashMap<>();
            var.put("schoolId", schoolId);
            var.put("chartType", "pillar-alarm");
            var.put("alarmInfo", data);
            var.put("begin_start_description", "报警柱触发报警");
            runtimeService.startProcessInstanceById(orgProcessInstanceById,var);
            result.setStatusCode(ResultCodeMsg.CODE_200);
        }else{
            result.setStatusCode(ResultCodeMsg.CODE_204);
            result.setMessage("流程图不存在！");
        }



        return result;
    }

    /**
     * 火灾触发报警
     *
     * @param data
     */
    public Result fireAlarm(String data) {
        Result result = new Result();
        Map<String, Object> reqMap = JSONObject.parseObject(data, Map.class);
        String schoolId = reqMap.get("orgCode").toString();
        result.setStatusCode(ResultCodeMsg.CODE_200);
        return result;
    }


    /**
     * 根据流程id 查流程详情(查所有的流程变量展示学生的数据-查走过的流程节点展示进行步骤-根据流程id和人员id查当前任务展示这个人是否是本任务的完成人)
     *
     * @param instanceId
     * @return
     */
    public Result selectInstanceInfo(String instanceId) {
        Result result = new Result();

        result.setStatusCode(ResultCodeMsg.CODE_200);
        //result.setData(reMap);
        return result;
    }

    public static String standardFmtsS(Date date) {
        if (EmptyChecker.isEmpty(date)) {
            return "";
        }
        SimpleDateFormat standardFmtsS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return standardFmtsS.format(date);
    }


    /**
     * 其中有一个保安到达报警地点
     *
     * @param json
     * @return
     */
    public Result securityArrival(String json) {
        Result result = new Result();
        Map<String, String> reqMap = JSONObject.parseObject(json, Map.class);
        String secuId = reqMap.get("secuId");
        String name = reqMap.get("name");
        String instanceId = reqMap.get("instanceId");
        String taskType = reqMap.get("taskType");

        if ("assignee".equals(taskType)) {
            //保安抵达任务
            Task task = taskService
                    .createTaskQuery()
                    .processInstanceId(instanceId)
                    .taskAssignee(secuId)
                    .singleResult();
            if (EmptyChecker.isEmpty(task)) {
                result.setStatusCode(ResultCodeMsg.CODE_501);
                return result;
            }
            String taskId = task.getId();
            //保安队长流程图指定代理人到达 - 删除reids
            jedisUtil.hdel("sos_handle", "sosSecurity_" + secuId + "_" + instanceId);
            //提交任务
            Map<String, Object> var = new HashMap<>();
            String nodekey = task.getTaskDefinitionKey() + "_description";
            var.put(nodekey, "【" + name + "-" + secuId + "】抵达报警点");
            taskService.complete(taskId, var);
        } else if ("candidate".equals(taskType)) {
            //保安抵达任务
            Task task = taskService
                    .createTaskQuery()
                    .processInstanceId(instanceId)
                    .taskCandidateUser(secuId)
                    .singleResult();
            if (EmptyChecker.isEmpty(task)) {
                result.setStatusCode(ResultCodeMsg.CODE_501);
                return result;
            }
            String taskId = task.getId();
            //保安自动接收任务流程图其中一候选人到达 - 删除redis
            List identityLinkList = taskService.getIdentityLinksForTask(taskId);
            for (Iterator iterator = identityLinkList.iterator(); iterator.hasNext(); ) {
                IdentityLink identityLink = (IdentityLink) iterator.next();
                if (identityLink.getUserId() != null) {
                    String canUserId = identityLink.getUserId();
                    String redisKey = "sosSecurity_" + canUserId + "_" + instanceId;
                    jedisUtil.hdel("sos_handle", redisKey);
                }
            }
            //将此保安设置为任务完成人并完成此任务
            Map<String, Object> var = new HashMap<>();
            var.put("handleFigure", secuId);
            String nodekey = task.getTaskDefinitionKey() + "_description";
            //String oldDes = runtimeService.getVariable(task.getExecutionId(), nodekey) + "";
            //var.put(nodekey, oldDes + "【" + name + "-" + secuId + "】抵达报警点");
            var.put(nodekey, "【" + name + "-" + secuId + "】抵达报警点");
            taskService.claim(taskId, secuId);
            taskService.complete(taskId, var);
        }

        //存报警细节信息
        //saveInsOfReach(secuId, reqMap.get("name"), reqMap.get("peopleType"), instanceId, taskType);

        result.setStatusCode(ResultCodeMsg.CODE_200);
        return result;

    }

    /**
     * 保安队长分配任务完成
     *
     * @param currentLoginUser
     * @param reqMap
     * @return
     */
    public Result gearTask(CurrentLoginUser currentLoginUser, Map reqMap) {
        Result result = new Result();

        return result;

    }

    /**
     * 保安查明情况 - 结束流程
     *
     * @param currentLoginUser
     * @param reqMap
     * @return
     */
    public Result overSos(CurrentLoginUser currentLoginUser, Map reqMap) {
        Result result = new Result();
        String taskId = reqMap.get("taskId") + "";
        String name = reqMap.get("name") + "";
        String assigneeId = currentLoginUser.getPhone() + "";
        Object alarmRecord = reqMap.get("alarmRecord");
        Task task = taskService
                .createTaskQuery()
                .taskId(taskId)
                .singleResult();
        if (assigneeId.equals(task.getAssignee())) {
            Map<String, Object> var = new HashMap<>();
            var.put("alarmRecord", alarmRecord);
            String nodekey = task.getTaskDefinitionKey() + "_description";
            var.put(nodekey, "【" + name + "-" + assigneeId + "】本次报警处理完毕");
            //taskService.setVariable(taskId, "alarmRecord", alarmRecord);
            taskService.complete(taskId, var);
            result.setStatusCode(ResultCodeMsg.CODE_200);
            result.setMessage("报警处理完毕");
            //存流程图细节
            //saveInsOfOver(task.getProcessInstanceId(), alarmRecord);
        } else {
            result.setStatusCode(ResultCodeMsg.CODE_501);
        }
        return result;
    }

    /**
     * 班主任处理sos报警
     *
     * @param currentLoginUser
     * @param reqMap
     * @return
     */
    public Result teacherHandle(CurrentLoginUser currentLoginUser, Map reqMap) {
        Result result = new Result();
        String taskId = reqMap.get("taskId") + "";
        String assigneeId = currentLoginUser.getPhone() + "";
        String isGoOn = reqMap.get("isGoOn") + "";
        Task task = taskService
                .createTaskQuery()
                .taskId(taskId)
                .singleResult();
        if (assigneeId.equals(task.getAssignee())) {
            String nodekey = task.getTaskDefinitionKey() + "_description";
            String offGoOnDes = "yes".equals(isGoOn) ? "其他组织介入处理" : "已经处理完毕";
            Map<String, Object> var = new HashMap<>();
            if (EmptyChecker.notEmpty(reqMap.get("teacherRecord"))) {
                var.put("teacherRecord", reqMap.get("teacherRecord"));
            }
            var.put(nodekey, "【" + reqMap.get("name") + "-" + assigneeId + "】处理完成");
            var.put("offGoOn", isGoOn);
            var.put("serialGateway_offGoOn_description", offGoOnDes);
            taskService.complete(taskId, var);
            result.setStatusCode(ResultCodeMsg.CODE_200);
            result.setMessage("教师处理完毕");
        } else {
            result.setStatusCode(ResultCodeMsg.CODE_501);
        }
        return result;
    }


    /**
     * 存某一保安已到达报警地点信息进mongo
     *
     * @param peopleId
     * @param name
     * @param peopleType
     */
    public void saveInsOfReach(String peopleId, String name, String peopleType, String instanceId, String taskType) {

        //要更新的进度信息
        Map<String, Object> instanceInfo = new HashMap<>();
        instanceInfo.put("peopleId", peopleId);
        instanceInfo.put("name", name);
        instanceInfo.put("peopleType", peopleType);

        //更新条件
        Map<String, Object> guide = new HashMap<>();
        guide.put("instanceId", instanceId);
        guide.put("data", instanceInfo);
        guide.put("handleFigure", peopleId);
        guide.put("taskType", taskType);

        restTemplate.postForObject(savaProcessAtReachUrl, guide, String.class);
    }

    /**
     * 存保安队长分配任务-有可能是sos报警，有可能是报警柱报警
     *
     * @param instanceId
     * @param taskId
     * @param gearId
     */
    public void saveInsOfGearTask(String instanceId, String taskId, String gearId) {
        String chartType = taskService.getVariable(taskId, "chartType").toString();

        //存redis数据
        Map<String, Object> redisInfo = new HashMap<>();
        redisInfo.put("chartType", chartType);
        redisInfo.put("instanceId", instanceId);
        redisInfo.put("taskType", "assignee");
        if ("sos-security".equals(chartType)) {
            String student = taskService.getVariable(taskId, "student").toString();
            Map<String, Object> studentInfo = JSONObject.parseObject(student, Map.class);
            redisInfo.put("student", studentInfo.get("Student"));
            redisInfo.put("orgCode", studentInfo.get("orgCode"));
            redisInfo.put("schoolId", studentInfo.get("schoolId"));
            redisInfo.put("gps", studentInfo.get("Gps"));
            redisInfo.put("sosSign", studentInfo.get("Sos-Sign"));
        } else if ("pillar-alarm".equals(chartType) || "fire-alarm".equals(chartType)) {
            String orgCode = taskService.getVariable(taskId, "schoolId").toString();
            String alarmInfo = taskService.getVariable(taskId, "alarmInfo").toString();
            redisInfo.put("orgCode", orgCode);
            redisInfo.put("schoolId", orgCode);
            redisInfo.put("alarmInfo", alarmInfo);
        }
        jedisUtil.hset("sos_handle", "sosSecurity_" + gearId + "_" + instanceId, JSONObject.toJSONString(redisInfo));

//                //存sos报警细节
//                Map<String, Object> sosMongo = new HashMap<>();
//                sosMongo.put("peopleId", gearId);
//                sosMongo.put("name", gearName);
//                sosMongo.put("peopleType", gearType);
//                sosMongo.put("processType", "sos-security");
//                sosMongo.put("instanceId", instanceId);
//
//                //要更新的进度信息
//                Map<String, Object> instanceInfoLea = new HashMap<>();
//                instanceInfoLea.put("peopleId", leaId);
//                instanceInfoLea.put("name", leaName);
//                instanceInfoLea.put("peopleType", leaPeopleType);
//
//                //更新条件
//                Map<String, Object> guide = new HashMap<>();
//                guide.put("gear", sosMongo);
//                guide.put("leader", instanceInfoLea);
//                guide.put("handleFigure", gearId);
//
//                restTemplate.postForObject(saveInsOfGearTaskUrl, guide, String.class);
    }

    /**
     * sos流程结束存信息进mongo
     *
     * @param alarmRecord
     * @param instanceId
     */
    public void saveInsOfOver(String instanceId, Object alarmRecord) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //更新条件
                Map<String, Object> guide = new HashMap<>();
                guide.put("instanceId", instanceId);
                guide.put("alarmRecord", alarmRecord);

                restTemplate.postForObject(savaProcessAtOverUrl, guide, String.class);
            }
        }).start();
    }

    /**
     * 电子围栏报警
     *
     * @param json
     */
    public Result fenceSos(String json) {
        Map<String, Object> reqMap = JSONObject.parseObject(json, Map.class);
        Map<String, Object> student = (Map) reqMap.get("student");
        List orgCodeList = (List) student.get("schools");
        student.remove("schools");
        //组装推送报警信息
        AlarmMessageInfo alarmMessageInfo = new AlarmMessageInfo();
        alarmMessageInfo.setMessageType(12);
        for (Object orgCode : orgCodeList) {
            student.put("orgCode", orgCode);
            student.put("schoolId", orgCode);
            reqMap.put("student", student);
            alarmMessageInfo.setExtData(JSONObject.toJSONString(reqMap));
            //推给熊涛涛1
            websocketService.receiveMessageInfo(JSONObject.toJSONString(alarmMessageInfo));
        }

        Result result = new Result();
        result.setStatusCode(ResultCodeMsg.CODE_200);
        return result;
    }

}

